package com.zj.sa_token.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.zj.sa_token.entity.UserInfoEntity;
import com.zj.sa_token.service.UserInfoService;
import com.zj.sa_token.util.avoid.AvoidRepeatableCommit;
import com.zj.sa_token.util.date.DateFacs;
import com.zj.sa_token.util.redis.RedisUtil;
import com.zj.sa_token.util.result.Result;
import com.zj.sa_token.util.result.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import webgis.tools.StringFacs;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

@CrossOrigin
@RestController
@RequestMapping("/user/")
@Api(value = "user", tags = "登录校验管理模块")
public class UserController {

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private RedisUtil redisUtil;

    @Value("${config.application.privateKey}")
    private String privateKey;

    // 测试登录，浏览器访问： http://localhost:8081/user/doLogin?username=zhang&password=123456
    @PostMapping("doLogin")
    @ApiOperation("登录")
    public Result doLogin(@RequestParam("userName") String userName, @RequestParam("password") String password, @RequestParam("code") String code) {
        // 此处仅作模拟示例，真实项目需要从数据库中查询数据进行比对
        if ("".equals(userName) || "".equals(password) || "".equals(code)) {
            return ResultUtil.error(-1, "用户名、密码、验证码均不能为空");
        }
        UserInfoEntity userInfoEntity = userInfoService.getUserInfoByUserName(userName);
        if (!StringFacs.isEmpty(userInfoEntity)) {
            String s_password = userInfoEntity.getPassword();
            String s_private = SaSecureUtil.rsaDecryptByPrivate(privateKey, s_password);//使用私密解密
            if (s_private.equals(password)) {
                String redis_code = redisUtil.get(userInfoEntity.getUserName()).toString();//获取redis的验证码内容
                if (!StringFacs.isEmpty(redis_code) && code.equals(redis_code)) {
                    redisUtil.del(userInfoEntity.getUserName());//验证成功，删除redis验证码
                    StpUtil.login(userInfoEntity.getId());
                    SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
                    return ResultUtil.success(tokenInfo);
                } else {

                    return ResultUtil.error(-1, "请重新填写验证码！");
                }

            } else {
                return ResultUtil.error(-1, "密码错误！");
            }
        }
        return ResultUtil.error(-1, "用户不存在！");
    }


    /**
     * 获取验证码
     *
     * @return
     * @ResponseBody没有页面，所以文字返回描述
     */
    @GetMapping("/getCode")
    @ResponseBody
    @ApiOperation("获取验证码")
    @AvoidRepeatableCommit(timeout = 60)
    public Result getCode(@RequestParam("userName") String userName) {
        if ("".equals(userName)) {
            return ResultUtil.error(-1, "用户名不能为空");
        }
        UserInfoEntity userInfoEntity = userInfoService.getUserInfoByUserName(userName);
        if (!StringFacs.isEmpty(userInfoEntity)) {

            if (!StringFacs.isEmpty(redisUtil.get(userName))) {
                //已存在code验证码
                return ResultUtil.error(-1, "请六十秒后重试");
            } else {
                //往redis中存入对象
                String randomString = getRandomString(4);
                redisUtil.set(userName, randomString);
                /*设置redis失效时间*/
                redisUtil.expire(userName, 60);
                Result result = new Result();
                result.setCode(200);
                result.setData(randomString);
                result.setMsg("验证码获取成功");
                return result;
            }
        }
        return ResultUtil.error(-1, "该用户不存在！");
    }

    //生成四位验证码
    public static String getRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    // 查询登录状态，浏览器访问： http://localhost:8081/user/isLogin
    @GetMapping("isLogin")
    @ApiOperation("查询登录状态")
    public String isLogin() {
        return "当前会话是否登录：" + StpUtil.isLogin();
    }


    // 查询 Token 信息  ---- http://localhost:8081/acc/tokenInfo
    @GetMapping("tokenInfo")
    @ApiOperation("查询 Token 信息")
    public Result tokenInfo() {
        return ResultUtil.success(StpUtil.getTokenInfo());
    }

    // 测试注销  ---- http://localhost:8081/user/logout
//    忽略拦截器
    @SaIgnore
    @GetMapping("logout")
    @ApiOperation("忽略拦截器")
    public Result logout() {
        StpUtil.logout();
        return ResultUtil.success();
    }

    // 测试配置拦截器  ---- http://localhost:8081/user/test
    @GetMapping("test")
    @ApiOperation("测试配置拦截器")
    public Result test() {
        return ResultUtil.success("11111111");
    }

    // 测试全局token异常返回  ---- http://localhost:8081/user/exceptionToten
    @GetMapping("exceptionToten")
    @ApiOperation("测试全局token异常返回")
    public Result exceptionToten() {
        return ResultUtil.success("11111111");
    }

    @GetMapping("/getnum")
    @ResponseBody
    @ApiOperation("测试流水编号生成")
    public String getnum() {
        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();

        /*第一种*/
        /*String timestamp = DateFacs.getTime("yyyy-MM-dd-HH-mm-ss-S");*/
        String timestamp = DateFacs.getTime("yyyy-MM-dd-HH-mm-ss");
        timestamp = timestamp.replaceAll("-", "");//毫秒级时间戳
        int lsdh = (int) (Math.random() * (9999 - 1000) + 1000);//产生1000-9999的随机数
        StringBuilder append1 = s1.append(timestamp).append(lsdh);
        System.out.println("时间戳的随机数----" + append1);

        /*第二种*/
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = simpleDateFormat.format(date);
        StringBuilder append2 = s2.append(format).append(lsdh);
        System.out.println("时间戳的随机数----" + append2);


        long l = System.currentTimeMillis();

        return s2.toString();
    }
}

